// <copyright file="Tooltip.cs" company="YUIAsp.Net">
// Copyright (c) 2009 All Right Reserved
// </copyright>
// <author>raul popescu</author>
// <email>dev@yuiasp.net</email>
// <date>2009-01-30</date>
// <summary>YUIAsp.Net File</summary>

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using YUIAspNet.Common;

[assembly: WebResource("YUIAspNet.Tooltip.Tooltip.js", "text/javascript")]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.Tooltip.container-skin.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.Blue.Tooltip.container-skin.css", "text/css", PerformSubstitution = true)]
namespace YUIAspNet
{
    /// <summary>
    /// Tooltip control.
    /// </summary>
    [ToolboxItem(true)]
    public class Tooltip : YUIScriptBaseControl, INamingContainer
    {
        List<string> _elements = new List<string>();
        Label _pnlTooltipContainer;
        Label _pnlTooltipContentContainer;

        /// <summary>
        /// Initializes a new instance of the <see cref="Slider"/> class.
        /// </summary>
        public Tooltip() : base("div")
        {
            this.Init += new EventHandler(Tooltip_Init);

            this.Style.Add("visibility", "hidden");
            this.Style.Add("position", "absolute");
            this.Style.Add("left", "-999");
            PreventOverlap = true;

            _pnlTooltipContainer = new Label();
            _pnlTooltipContentContainer = new Label();
        }

        /// <summary>
        /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            _pnlTooltipContainer.ID = "content";
            this.Controls.Add(_pnlTooltipContainer);

            _pnlTooltipContentContainer.ID = "ttc";
            this.Controls.Add(_pnlTooltipContentContainer);
        }

        void Tooltip_Init(object sender, EventArgs e)
        {
            if (this.ContentTemplate != null)
            {
                this.ContentTemplate.InstantiateIn(_pnlTooltipContentContainer);
            }
        }

        /// <summary>
        /// Registers the style sheets for the current control.
        /// Must be overriden in the parent control to add any css file reference.
        /// </summary>
        protected override void RegisterStyleSheets()
        {
            //todo: sam used!
            RegisterEmbeddedStylesheet("Tooltip", "container-skin.css");    
        }

        /// <summary>
        /// Registers any additional scripts to include for this control.
        /// </summary>
        protected override void RegisterScriptReferences()
        {
            AddScriptReference(new ScriptReference("YUIAspNet.Tooltip.Tooltip.js", GetType().Assembly.FullName));
        }

        /// <summary>
        /// Register the values to send to the client control for initialization.
        /// </summary>
        protected override void RegisterClientInitialization()
        {
            AddProperty("AutoDismissDelay", AutoDismissDelay);

            //try and convert ID's to ClientID
            for (int i = 0; i < _elements.Count; i++)
            {
                Control ctl = this.Parent.FindControl(_elements[i]);
                if (ctl != null)
                    _elements[i] = ctl.ClientID;
            }
            AddProperty("AttachToElements", _elements);
            AddProperty("HideDelay", HideDelay);
            AddProperty("PreventOverlap", PreventOverlap);
            AddProperty("ShowDelay", ShowDelay);
            AddProperty("Effect", Effect);
            AddProperty("UseIFrame", UseIFrame);
            AddProperty("TooltipContainer", _pnlTooltipContainer.ClientID);
            AddProperty("TooltipContentContainer", _pnlTooltipContentContainer.ClientID);

            if (!string.IsNullOrEmpty(OnClientMouseOver))
                AddEvent("OnMouseOver", OnClientMouseOver);
            if (!string.IsNullOrEmpty(OnClientMouseOut))
                AddEvent("OnMouseOut", OnClientMouseOut);
            if (!string.IsNullOrEmpty(OnClientContextTrigger))
                AddEvent("OnContextTrigger", OnClientContextTrigger);
        }

        #region Public properties

        /// <summary>
        /// The number of milliseconds to wait before automatically dismissing a Tooltip 
        /// after the mouse has been resting on the context element. 
        /// </summary>
        public int AutoDismissDelay { get; set; }

        /// <summary>
        /// Gets or sets the element to attach to.
        /// </summary>
        public string AttachToElement 
        {
            get 
            {
                if (_elements.Count == 0)
                    return null;

                return _elements[0];
            }
            set 
            {
                if (!_elements.Contains(value))
                    _elements.Add(value);
            }
        }

        /// <summary>
        /// Gets or sets the element list to attach to.
        /// </summary>
        /// <value>The attach to elements.</value>
        public string[] AttachToElements 
        {
            get { return _elements.ToArray(); }
            set { _elements.AddRange(value); } 
        }

        /// <summary>
        /// Gets or sets the element list to attach to.
        /// The elements must be separated by a comma.
        /// </summary>
        /// <value>The attach to element list.</value>
        public string AttachToElementList
        {
            get { return string.Join(",", _elements.ToArray()); }
            set { _elements = new List<string>(value.Split(',')); }
        }

        /// <summary>
        /// The number of milliseconds to wait before hiding a Tooltip after mouseout. 
        /// </summary>
        public int HideDelay { get; set; }

        /// <summary>
        /// Specifies whether the Tooltip should be kept from overlapping its context element. 
        /// </summary>
        public bool PreventOverlap { get; set; }

        /// <summary>
        /// The number of milliseconds to wait before showing a Tooltip on mouseover. 
        /// </summary>
        public bool ShowDelay { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether to use IFrame.
        /// </summary>
        public bool UseIFrame { get; set; }

        /// <summary>
        /// Gets or sets the content of the tooltip.
        /// </summary>
        /// <value>The content.</value>
        public string Content 
        {
            get 
            {
                if (_pnlTooltipContentContainer.Controls.Count > 0 && _pnlTooltipContentContainer.Controls[0] is LiteralControl)
                    return (_pnlTooltipContentContainer.Controls[0] as LiteralControl).Text;

                return null;
            }
            set 
            {
                _pnlTooltipContentContainer.Controls.Clear();
                _pnlTooltipContentContainer.Controls.Add(new LiteralControl(value)); 
            } 
        }

        /// <summary>
        /// Gets or sets the content template.
        /// </summary>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate ContentTemplate { get; set; }

        /// <summary>
        /// Gets or sets the show effect.
        /// </summary>
        /// <value>The effect.</value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ContainerEffect Effect { get; set; }

        /// <summary>
        /// Gets or sets callback for the mouse over event.
        /// </summary>
        /// <value>The on client mouse over.</value>
        public string OnClientMouseOver { get; set; }

        /// <summary>
        /// Gets or sets callback for the mouse out event.
        /// </summary>
        /// <value>The on client mouse out.</value>
        public string OnClientMouseOut { get; set; }

        /// <summary>
        /// Gets or sets callback for the tooltip trigger event.
        /// </summary>
        /// <value>The on client context trigger.</value>
        public string OnClientContextTrigger { get; set; }

        #endregion
    }
}
